/**
 * 
 */
package ma.moliere.presentation.controleur;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import ma.moliere.commun.FonctionnelleException;
import ma.moliere.domaine.IEleveDomaine;
import ma.moliere.domaine.IGestionInscriptionDomaine;
import ma.moliere.domaine.IParametrage;
import ma.moliere.persistance.oe.Anneescolaire;
import ma.moliere.persistance.oe.Inscription;
import ma.moliere.presentation.modele.CreationEleveModele;
import ma.moliere.transverse.vo.AbsenceAffiche;
import ma.moliere.transverse.vo.ClasseAffichee;
import ma.moliere.transverse.vo.EleveAffiche;
import ma.moliere.transverse.vo.ReglementAffiche;
import ma.moliere.transverse.vo.TarifAffiche;

import org.apache.commons.collections.CollectionUtils;
import org.richfaces.event.FileUploadEvent;
import org.richfaces.log.LogFactory;
import org.richfaces.log.Logger;
import org.richfaces.model.UploadedFile;

/**
 * @author SASMAMI Controleur pour la gestion des inscrptions des élèves.
 * 
 */
public class GestionInscriptionControleur implements Serializable {

	/**
	 * serialVersionUID.
	 */
	private static final long serialVersionUID = 8436224541447776768L;
	private static Logger LOGGER = LogFactory.getLogger(GestionInscriptionControleur.class);

	private static final Logger logger = LogFactory.getLogger(GestionInscriptionControleur.class);

	/** Injection pour l'accès au domaine. */
	private IEleveDomaine eleveDomaine;
	private IParametrage parametrageDomaine;
	private IGestionInscriptionDomaine inscriptionDomaine;

	/** Injection pour l'accès au modele. */
	private CreationEleveModele modele;

	public void setEleveDomaine(final IEleveDomaine eleveDomaine) {
		this.eleveDomaine = eleveDomaine;
	}

	public CreationEleveModele getModele() {
		if (null == modele) {
			modele = new CreationEleveModele();
		}
		return modele;
	}

	public void setModele(final CreationEleveModele modele) {
		this.modele = modele;
	}

	public void setParametrageDomaine(final IParametrage parametrageDomaine) {
		this.parametrageDomaine = parametrageDomaine;
	}

	public void setInscriptionDomaine(final IGestionInscriptionDomaine inscriptionDomaine) {
		this.inscriptionDomaine = inscriptionDomaine;
	}

	public GestionInscriptionControleur() {

	}

	/************************** ZONE DES ACTIONS ECRAN **************/

	public final String afficherEcrCreationEleve() {
		chargerAbsences();
		chargerAnnees();
		// TODO remttre le code dés que l'années est setté lors de la connexion
		// chargerReglement(getModele().getIdAnneeScolaire());
		return "ECR_CREATION_ELEVE";
	}

	public void chargerAbsences() {
		getModele().getAbsences().clear();
		List < AbsenceAffiche > absences = eleveDomaine.rechercher(getModele().getEleve().getMatricule(), getModele()
			.getIdAnneeScolaire());
		getModele().getAbsences().addAll(absences);
		LOGGER.debug("Chargement de la liste des absences");
		LOGGER.debug("La liste des absence pour le matricule " + getModele().getEleve().getMatricule() + " = " + absences.size());
	}

	public void chargerAnnees() {
		getModele().getAnnesScolairesItems().clear();
		List < Anneescolaire > annees = new ArrayList < Anneescolaire >();
		annees = parametrageDomaine.rechercherAnnees();
		if (annees != null && !annees.isEmpty()) {
			SelectItem item = null;
			for (Anneescolaire annee : annees) {
				item = new SelectItem();
				item.setLabel(annee.getLibelle());
				item.setValue(annee.getId());
				getModele().getAnnesScolairesItems().add(item);
			}
		} else {
			// Ajouter message d'erreur.
			// rester sur la meme page
		}
	}

	public void chargerClasses() {
		getModele().getClassesItems().clear();
		// chargement des années scolaire et des classes

		List < ClasseAffichee > classes = new ArrayList < ClasseAffichee >();
		classes = parametrageDomaine.rechercherClasses();

		// chargement des classes
		if (classes != null && !classes.isEmpty()) {
			SelectItem item = null;
			for (ClasseAffichee classe : classes) {
				item = new SelectItem();
				item.setLabel(classe.getLibelle());
				item.setValue(classe.getId());
				getModele().getClassesItems().add(item);
			}
		} else {
			// Ajouter message d'erreur.
			// rester sur la meme page
		}
	}

	/** Ecran d'inscription des élèves */
	public String afficherEcranInscription() {
		// vider le modele.
		setModele(null);
		chargerClasses();
		chargerAnnees();
		return "ECR_INSCRIPTION";
	}

	/**
	 * Inscription pour la première fois.Ici on enregistre seuelement l'identité de l'élève et la classe et les options trans et
	 * garderie. Le rrste des données seront enregistrées lors de la consulatation.
	 * 
	 * @return : String.
	 */
	public final String validerInscription() {

		// Reglements
		List < ReglementAffiche > regelements = new ArrayList < ReglementAffiche >();

		getModele().getInscription().setDateinscription(Calendar.getInstance().getTime());

		try {
			Inscription insc = inscriptionDomaine.enregistrerInscription(getModele().getInscription(), getModele()
				.getIdAnneeScolaire(), getModele().getIdClasse(), getModele().getEleve());
			// frais inscription
			ReglementAffiche fraisInscription = new ReglementAffiche();
			fraisInscription.setNature("Frais inscription");
			ClasseAffichee classe = parametrageDomaine.rechercherClasseParId(getModele().getIdClasse());
			TarifAffiche tarif = parametrageDomaine.rechercherTarif(classe.getLibelle());
			if (tarif == null) {
				FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur: Aucun tarif n'a été trouvé. ",
					null);
				FacesContext context = FacesContext.getCurrentInstance();
				context.addMessage(null, facesMsg);
				return null;
			}
			fraisInscription.setMontant(tarif.getInscription());
			fraisInscription.setTransport("");
			fraisInscription.setGarderie("");
			fraisInscription.setDatelimite(Calendar.getInstance().getTime());
			fraisInscription.setInscriptionId(insc.getId());
			regelements.add(fraisInscription);
			// Mensualités
			regelements.add(creerReglement("Septembre", "9", insc.getId(), tarif));
			regelements.add(creerReglement("Octobre", "10", insc.getId(), tarif));
			regelements.add(creerReglement("Novembre", "11", insc.getId(), tarif));
			regelements.add(creerReglement("Décembre", "12", insc.getId(), tarif));
			regelements.add(creerReglement("Janvier", "1", insc.getId(), tarif));
			regelements.add(creerReglement("Février", "2", insc.getId(), tarif));
			regelements.add(creerReglement("Mars", "3", insc.getId(), tarif));
			regelements.add(creerReglement("Avril", "4", insc.getId(), tarif));
			regelements.add(creerReglement("Mai", "5", insc.getId(), tarif));
			regelements.add(creerReglement("Juin", "6", insc.getId(), tarif));

			for (ReglementAffiche reg : regelements) {
				inscriptionDomaine.ajouterReglement(reg);
			}
			getModele().setEleve(null);
			FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Inscription validée sous le matricule :  "
				+ insc.getMatricule(), null);
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, facesMsg);
			// on vide le modele pour créer un nouvel eleve

		} catch (FonctionnelleException e) {
			FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur:  " + e.getMessage(), null);
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, facesMsg);
			return null;
		}

		return null;
	}

	private ReglementAffiche creerReglement(final String nature, final String mois, final Long inscription,
		final TarifAffiche tarif) {
		ReglementAffiche reg = new ReglementAffiche();
		reg.setNature(nature);
		reg.setInscriptionId(inscription);
		reg.setMontant(tarif.getMensualite() + tarif.getTransport());
		// TODO la date limite doit etre revu après validation du mécanisme de gestion des retard de paiement.
		reg.setDatelimite(Calendar.getInstance().getTime());
		if (getModele().getTransport().equals("oui")) {
			reg.setTransport("Oui");

		} else {
			reg.setTransport("Non");
		}
		if (getModele().getGarderie().equals("oui")) {
			reg.setGarderie("Oui");
		} else {
			reg.setGarderie("Non");
		}

		return reg;
	}

	public String afficherContact() {
		return "ECR_SAISIE_CONTACT";
	}

	public String enregistrerContact() {
		getModele().getRencontre().setCreateur("USER");
		getModele().getRencontre().setDate(Calendar.getInstance().getTime());
		inscriptionDomaine.ajouterRencontre(getModele().getRencontre());
		return null;
	}

	/** Permet d'enregistrer les donnée d'un élève */
	public String validerModificationEleve() {

		EleveAffiche eleve = eleveDomaine.modifier(getModele().getEleve());
		getModele().setEleve(eleve);

		FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "La transaction a été validée avec succès.", null);
		FacesContext context = FacesContext.getCurrentInstance();
		context.addMessage(null, facesMsg);

		return null;
	}

	public void listener(final FileUploadEvent event) {
		UploadedFile file = event.getUploadedFile();
		getModele().getEleve().setPhoto(file.getData());

	}

	public void paint(final OutputStream stream, final Object object) throws IOException {
		if (getModele().getEleve().getPhoto() != null) {
			stream.write(getModele().getEleve().getPhoto());
			stream.close();
		}
	}

	/**
	 * chargement des reglement de l'eleve courant.
	 * 
	 * @param event
	 *            : changed value
	 */
	public final void anneeChangedValue(final ValueChangeEvent event) {
		if (null != event.getNewValue()) {
			chargerReglement((Long) event.getNewValue());

		}
	}

	public final void chargerReglement(final Long idannee) {

		getModele().getReglementsAffiches().clear();
		List < ReglementAffiche > reglements = new ArrayList < ReglementAffiche >();
		List < String > matricules = new ArrayList < String >();
		List < Long > ids = new ArrayList < Long >();
		matricules.add(getModele().getEleve().getMatricule());
		Inscription inscription = null;
		List < Inscription > inscriptions = inscriptionDomaine.rechercherInscription(matricules, idannee);
		if (CollectionUtils.isNotEmpty(inscriptions)) {
			inscription = inscriptions.get(0);
			ids.add(inscription.getId());
			reglements = inscriptionDomaine.rechercherReglementsParInscription(ids);
			getModele().getReglementsAffiches().addAll(reglements);
		} else {

			FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Aucune inscription trouvée pour le matricule "
				+ getModele().getEleve().getMatricule(), null);
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, facesMsg);
		}
	}

}
